home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** Program: MacShell
- ** File: AECustom.c
- ** Written by: Eric Soldan
- **
- ** Copyright © 1990-1991 Apple Computer, Inc.
- ** All rights reserved.
- */
-
-
-
- /*****************************************************************************/
-
-
-
- #include "MacShell.h" /* Get the MacShell includes/typedefs, etc. */
- #include "MacShellCommon.h" /* Get the stuff in common with rez. */
- #include "MacShell.protos" /* Get the prototypes for MacShell. */
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __TEXTEDITCONTROL__
- #include "TextEditControl.h"
- #endif
-
- #ifdef THINK_C
- #include "Utilities.h"
- #else
- #ifndef __UTILITIES__
- #include <Utilities.h>
- #endif
- #endif
-
-
-
- /*****************************************************************************/
-
-
-
- extern Boolean gHasAppleEvents;
- extern RgnHandle gCursorRgn;
-
- static pascal OSErr ReceiveMessage(AppleEvent *message, AppleEvent *reply, long refcon);
-
-
-
- /*****************************************************************************/
-
-
-
- static triplets keywordsToInstall[] = {
- { kCustomEventClass, keyAppMessage, (ProcPtr)ReceiveMessage }
- }; /* These are the custom AppleEvents. */
-
-
-
- /*****************************************************************************/
- /*****************************************************************************/
-
-
-
- /* InitCustomAppleEvents
- **
- ** Install our custom AppleEvents. This is done in addition to installing
- ** the required AppleEvents. InitAppleEvents, which installs the required
- ** AppleEvents, must be called first, since it sets up some global values.
- */
-
- #pragma segment AppleEvents
- void InitCustomAppleEvents(void)
- {
- OSErr err;
- short i;
-
- if (gHasAppleEvents) {
- for (i = 0; i < (sizeof(keywordsToInstall) / sizeof(triplets)); ++i) {
- err = AEInstallEventHandler(
- keywordsToInstall[i].theEventClass, /* What class to install. */
- keywordsToInstall[i].theEventID, /* Keywords to install. */
- keywordsToInstall[i].theHandler, /* The AppleEvent handler. */
- 0L, /* Unused refcon. */
- false /* Only for our app. */
- );
-
- if (err) {
- Alert(rErrorAlert, (ModalFilterProcPtr)alertFilter);
- return;
- }
- }
- }
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* SendMessage
- **
- */
-
- #pragma segment AppleEvents
- OSErr SendMessage(FileRecHndl frHndl, short messageType)
- {
- AEAddressDesc remoteLoc;
- OSErr err;
- AppleEvent theAevt, reply;
- long windID[2];
- short i;
- WindowPtr oldPort;
- #if MACSHELL_VERSION
- TEHandle te;
- char hstate;
- Handle hText;
- long size;
- #endif
-
- if (!(*frHndl)->connect.connected) return(noErr);
-
- oldPort = SetFilePort(frHndl);
-
- theAevt.dataHandle = reply.dataHandle = nil;
- /* Make sure disposing of the descriptors is okay in all cases.
- ** This will not be necessary after 7.0b3, since the calls that
- ** attempt to create the descriptors will nil automatically
- ** upon failure. */
-
- remoteLoc = (*frHndl)->connect.remoteLoc;
-
- err = AECreateAppleEvent( /* CREATE EMPTY APPLEEVENT. */
- kCustomEventClass, /* Event class. */
- typeAppMessage, /* Event ID. */
- &remoteLoc, /* Address of receiving app. */
- kAutoGenerateReturnID, /* This value causes the */
- /* AppleEvent manager to */
- /* assign a return ID that */
- /* is unique to the session. */
- kAnyTransactionID, /* Ignore transaction ID. */
- &theAevt /* Location of event. */
- );
-
- if (!err) { /* Say what the message is. */
- AEPutParamPtr(
- &theAevt,
- keyDirectObject,
- typeShortInteger,
- (Ptr)&messageType,
- sizeof(short)
- );
- }
-
- if (!err) { /* Say what window message is for. */
- for (i = 0; i < 2; ++i) windID[i] = (*frHndl)->connect.windowID[i];
- AEPutParamPtr(
- &theAevt,
- keyWindowID,
- typeDoubleLong,
- (Ptr)&windID[0],
- 2 * sizeof(long)
- );
- }
-
- /* The stuff that applies to all messages is now done. Now specifically
- ** handle all the different message types. */
-
- if (!err) {
- switch (messageType) {
-
- case kDisconnectMssg:
- /* All the information we need is already in the AppleEvent. */
- break;
-
- #if MACSHELL_VERSION
- case kTextMssg:
- te = (*frHndl)->doc.outBox;
- hText = (*te)->hText;
- hstate = LockHandleHigh(hText);
- size = (*te)->teLength;
- err = AEPutParamPtr(
- &theAevt,
- keyAppMessage,
- typeTextMessage,
- *hText,
- size
- );
- HSetState(hText, hstate);
- break;
- #endif
-
- }
- }
-
- if (!err) { /* If everything looks good... */
- err = AESend( /* SEND APPLEEVENT. */
- &theAevt, /* Our Apple Event to send. */
- &reply, /* We may have a reply. */
- kAENoReply, /* Don't wait for reply. */
- kAENormalPriority, /* App. send priority. */
- 0, /* We aren't waiting. */
- nil, /* No wait, no filter. */
- nil /* EventFilterProcPtr. */
- );
- }
-
- #if MACSHELL_VERSION
- if (!err) {
- if (messageType == kTextMssg)
- CTESetSelect(0, (*te)->teLength, te);
- /* Select all the text so entering the next message
- ** is more convenient. */
- }
- #endif
-
- AEDisposeDesc(&theAevt);
- AEDisposeDesc(&reply);
- /* Dispose of the descriptors, created or not.
- ** If not created, no harm done by calling. */
-
- SetPort(oldPort);
- return(err);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment AppleEvents
- pascal OSErr ReceiveMessage(AppleEvent *message, AppleEvent *reply, long refcon)
- {
- #pragma unused (refcon)
-
- OSErr err;
- short messageType;
- WindowPtr window;
- FileRecHndl frHndl;
- DescType actualType;
- long actualSize, windID[2];
- AEAddressDesc remoteLoc;
- #if MACSHELL_VERSION
- Handle mssgData;
- char hstate;
- long mssgSize;
- #endif
-
- err = noErr;
- AEPutParamPtr( /* RETURN REPLY ERROR, EVEN IF NONE... */
- reply, /* The AppleEvent. */
- keyReplyErr, /* AEKeyword */
- typeShortInteger, /* Desired type. */
- (Ptr)&err, /* Pointer to area for data. */
- sizeof(short) /* Size of data area. */
- );
-
- err = AEGetParamPtr( /* GET THE MESSAGE TYPE. */
- message, /* The AppleEvent. */
- keyDirectObject, /* AEKeyword */
- typeShortInteger, /* Desired type. */
- &actualType, /* Type code. */
- (Ptr)&messageType, /* Pointer to area for data. */
- 2 * sizeof(long), /* Size of data area. */
- &actualSize /* Returned size of data. */
- );
-
- if (!err) {
- err = AEGetParamPtr( /* GET WINDOW MESSAGE IS FOR. */
- message, /* The AppleEvent. */
- keyWindowID, /* AEKeyword */
- typeDoubleLong, /* Desired type. */
- &actualType, /* Type code. */
- (Ptr)&windID[0], /* Pointer to area for data. */
- 2 * sizeof(long), /* Size of data area. */
- &actualSize /* Returned size of data. */
- );
- }
-
- if (!err) { /* See if the requested window exists... */
- if (window = GetAEWindow(windID[1], windID[0])) {
- frHndl = (FileRecHndl)GetWRefCon(window);
- /* The window still exists... */
- }
- else
- err = userCanceledErr;
- /* User (or computer) canceled connection by disconnecting improperly. */
- }
-
- if (!err) { /* If everything is cool, then do the specific task... */
-
- switch(messageType) {
-
- case kDisconnectMssg:
- remoteLoc = (*frHndl)->connect.remoteLoc;
- AEDisposeDesc(&remoteLoc);
- (*frHndl)->connect.connected = false;
- AdjustMenus();
- break;
-
- #if MACSHELL_VERSION
- case kTextMssg:
- if (!err) { /* Determine the size of the data... */
- err = AEGetParamPtr(
- message, /* The AppleEvent. */
- keyAppMessage, /* AEKeyword */
- typeTextMessage, /* Desired type. */
- &actualType, /* Type code. */
- nil, /* Pointer to area for data. */
- 0, /* Size of data area. */
- &mssgSize /* Returned size of data. */
- );
- }
- mssgData = nil;
- if (!err) { /* Get the data... */
- mssgData = NewHandle(mssgSize);
- if (mssgData) {
- hstate = LockHandleHigh(mssgData);
- err = AEGetParamPtr(
- message, /* The AppleEvent. */
- keyAppMessage, /* AEKeyword */
- typeTextMessage, /* Desired type. */
- &actualType, /* Type code. */
- *mssgData, /* Pointer to area for data. */
- mssgSize, /* Size of data area. */
- &actualSize /* Returned size of data. */
- );
- }
- else err = memFullErr;
- }
- if (!err) {
- BeginContent(window);
- mssgData = CTESwapText((*frHndl)->doc.inBox, mssgData, true);
- EndContent(window);
- }
- if (mssgData) DisposHandle(mssgData);
- if (!err) NotifyUser();
- break;
- #endif
-
- }
- }
-
- return(err);
- }
-
-
-
-